๊ฐ๋ ฅํ ๋ชจ๋ธ ์ ํ์ ์ํ Scikit-learn์ ๊ต์ฐจ ๊ฒ์ฆ ์ ๋ต์ ๋ง์คํฐํ์ธ์. K-Fold, ๊ณ์ธต๋ณ, ์๊ณ์ด CV ๋ฑ์ ์ค์ฉ์ ์ธ Python ์์ ์ ํจ๊ป ๊ธ๋ก๋ฒ ๋ฐ์ดํฐ ๊ณผํ์์๊ฒ ์ ๊ณตํฉ๋๋ค.
Scikit-learn ๋ง์คํฐํ๊ธฐ: ๋ชจ๋ธ ์ ํ์ ์ํ ๊ฐ๋ ฅํ ๊ต์ฐจ ๊ฒ์ฆ ์ ๋ต ๊ธ๋ก๋ฒ ๊ฐ์ด๋
\n\n๊ด๋ํ๊ณ ์ญ๋์ ์ธ ๋จธ์ ๋ฌ๋ ํ๊ฒฝ์์, ์์ธก ๋ชจ๋ธ์ ๊ตฌ์ถํ๋ ๊ฒ์ ์ ํฌ์ ์ ๋ฐ์ ๋ถ๊ณผํฉ๋๋ค. ๋๋จธ์ง ์ ๋ฐ์ด์ ๋๊ฐ์ด ์ค์ํ ๋ถ๋ถ์ ์ด๋ฌํ ๋ชจ๋ธ์ด ๋ณด์ง ๋ชปํ ๋ฐ์ดํฐ์์๋ ์์ ์ ์ผ๋ก ์๋ํ๋๋ก ์๊ฒฉํ๊ฒ ํ๊ฐํ๋ ๊ฒ์ ๋๋ค. ์ ์ ํ ํ๊ฐ ์์ด๋ ๊ฐ์ฅ ์ ๊ตํ ์๊ณ ๋ฆฌ์ฆ์กฐ์ฐจ ์คํด๋ฅผ ๋ถ๋ฌ์ผ์ผํค๋ ๊ฒฐ๋ก ๊ณผ ์ต์ ํ๋์ง ์์ ๊ฒฐ์ ์ผ๋ก ์ด์ด์ง ์ ์์ต๋๋ค. ์ด๋ฌํ ๋ฌธ์ ๋ ๋ชจ๋ ์ฐ์ ๊ณผ ์ง์ญ์ ๋ฐ์ดํฐ ๊ณผํ์์ ๋จธ์ ๋ฌ๋ ์์ง๋์ด์๊ฒ ์ํฅ์ ๋ฏธ์น๋ ๋ณดํธ์ ์ธ ๊ณผ์ ์ ๋๋ค.
\n\n์ด ํฌ๊ด์ ์ธ ๊ฐ์ด๋๋ ๊ฐ๋ ฅํ ๋ชจ๋ธ ํ๊ฐ ๋ฐ ์ ํ์ ์ํ ๊ฐ์ฅ ๊ทผ๋ณธ์ ์ด๊ณ ๊ฐ๋ ฅํ ๊ธฐ์ ์ค ํ๋์ธ Python์ ์ธ๊ธฐ ๋ผ์ด๋ธ๋ฌ๋ฆฌ Scikit-learn ๋ด์์ ๊ตฌํ๋ ๊ต์ฐจ ๊ฒ์ฆ์ ๋ํด ์์ธํ ์ค๋ช ํฉ๋๋ค. ๋ฐ๋์ ๋ ธ๋ จํ ์ ๋ฌธ๊ฐ๋ , ๋ฑ ๊ฐ๋ก๋ฅด์ ์ ์ง ๋ฐ์ดํฐ ๋ถ์๊ฐ๋ , ์ํ์ธ๋ฃจ์ ๋จธ์ ๋ฌ๋ ์ฐ๊ตฌ์์ด๋ , ์ด๋ฌํ ์ ๋ต์ ์ดํดํ๊ณ ์ ์ฉํ๋ ๊ฒ์ ์ ๋ขฐํ ์ ์๊ณ ํจ๊ณผ์ ์ธ ๋จธ์ ๋ฌ๋ ์์คํ ์ ๊ตฌ์ถํ๋ ๋ฐ ๊ฐ์ฅ ์ค์ํฉ๋๋ค.
\n\n๋ค์ํ ๊ต์ฐจ ๊ฒ์ฆ ๊ธฐ์ ์ ํ์ํ๊ณ , ๊ทธ ๋ฏธ๋ฌํ ์ฐจ์ด๋ฅผ ์ดํดํ๋ฉฐ, ๋ช ํํ๊ณ ์คํ ๊ฐ๋ฅํ Python ์ฝ๋๋ฅผ ์ฌ์ฉํ์ฌ ์ค์ ์ ์ฉ์ ์์ฐํ ๊ฒ์ ๋๋ค. ์ฐ๋ฆฌ์ ๋ชฉํ๋ ํน์ ๋ฐ์ดํฐ์ ๊ณผ ๋ชจ๋ธ๋ง ๋ฌธ์ ์ ๋ํ ์ต์ ์ ์ ๋ต์ ์ ํํ ์ ์๋ ์ง์์ ์ ๊ณตํ์ฌ, ๋ชจ๋ธ์ด ์ ์ผ๋ฐํ๋๊ณ ์ผ๊ด๋ ์ฑ๋ฅ์ ์ ๊ณตํ๋๋ก ๋ณด์ฅํ๋ ๊ฒ์ ๋๋ค.
\n\n๊ณผ์ ํฉ ๋ฐ ๊ณผ์์ ํฉ์ ์ํ: ์ ๊ฐ๋ ฅํ ํ๊ฐ๊ฐ ์ค์ํ๊ฐ
\n\n๊ต์ฐจ ๊ฒ์ฆ์ ๋ํด ๊น์ด ํ๊ณ ๋ค๊ธฐ ์ ์, ๋จธ์ ๋ฌ๋์ ๋ ๊ฐ์ง ์ฃผ์ ์ , ์ฆ ๊ณผ์ ํฉ(overfitting)๊ณผ ๊ณผ์์ ํฉ(underfitting)์ ์ดํดํ๋ ๊ฒ์ด ํ์์ ์ ๋๋ค.
\n\n- \n
- ๊ณผ์ ํฉ: ์ด๋ ๋ชจ๋ธ์ด ํ๋ จ ๋ฐ์ดํฐ๋ฅผ ๋๋ฌด ์ ํ์ตํ์ฌ ์๋ก์ด, ๋ณด์ง ๋ชปํ ๋ฐ์ดํฐ์ ์ผ๋ฐํ๋์ง ์๋ ๋ ธ์ด์ฆ์ ํน์ ํจํด๊น์ง ํฌ์ฐฉํ ๋ ๋ฐ์ํฉ๋๋ค. ๊ณผ์ ํฉ๋ ๋ชจ๋ธ์ ํ๋ จ ์ธํธ์์๋ ํ์ํ ์ฑ๋ฅ์ ๋ณด์ด์ง๋ง ํ ์คํธ ๋ฐ์ดํฐ์์๋ ์ฑ๋ฅ์ด ์ ์กฐํฉ๋๋ค. ํน์ ์ํ์ ๋ต์ ์๊ธฐํ์ง๋ง ๊ฐ์ ์ฃผ์ ์ ๋ํด ์ฝ๊ฐ ๋ค๋ฅธ ์ง๋ฌธ์๋ ์ด๋ ค์์ ๊ฒช๋ ํ์์ ์์ํด ๋ณด์ธ์. \n
- ๊ณผ์์ ํฉ: ๋ฐ๋๋ก ๊ณผ์์ ํฉ์ ๋ชจ๋ธ์ด ํ๋ จ ๋ฐ์ดํฐ์ ๊ธฐ๋ณธ ํจํด์ ํฌ์ฐฉํ๊ธฐ์๋ ๋๋ฌด ๋จ์ํ ๋ ๋ฐ์ํฉ๋๋ค. ์ด๋ ํ๋ จ ๋ฐ์ดํฐ์ ํ ์คํธ ๋ฐ์ดํฐ ๋ชจ๋์์ ์ฑ๋ฅ์ด ์ ์กฐํฉ๋๋ค. ์ด๊ฒ์ ๊ธฐ๋ณธ ๊ฐ๋ ์ ํ์ ํ์ง ๋ชปํด ๊ฐ๋จํ ์ง๋ฌธ์กฐ์ฐจ ๋ตํ์ง ๋ชปํ๋ ํ์๊ณผ ๊ฐ์ต๋๋ค. \n
์ ํต์ ์ธ ๋ชจ๋ธ ํ๊ฐ๋ ์ข ์ข ๊ฐ๋จํ ํ๋ จ/ํ ์คํธ ๋ถํ ์ ํฌํจํฉ๋๋ค. ์ข์ ์์์ ์ด์ง๋ง, ๋จ์ผ ๋ถํ ์ ๋ฌธ์ ๊ฐ ๋ ์ ์์ต๋๋ค:
\n\n- \n
- ์ฑ๋ฅ์ด ํน์ ๋ฌด์์ ๋ถํ ์ ํฌ๊ฒ ์์กดํ ์ ์์ต๋๋ค. "์ด ์ข์" ๋ถํ ์ ์ข์ง ์์ ๋ชจ๋ธ์ ์ข๊ฒ ๋ณด์ด๊ฒ ํ ์ ์๊ณ , ๊ทธ ๋ฐ๋๋ ๋ง์ฐฌ๊ฐ์ง์ ๋๋ค. \n
- ๋ฐ์ดํฐ์ ์ด ์์ผ๋ฉด ๋จ์ผ ๋ถํ ์ ํ๋ จ ๋ฐ์ดํฐ ๋๋ ํ ์คํธ ๋ฐ์ดํฐ๋ฅผ ์ ๊ฒ ์๋ฏธํ๋ฉฐ, ๋ ๋ค ์ ๋ขฐํ ์ ์๋ ์ฑ๋ฅ ์ถ์ ์ผ๋ก ์ด์ด์ง ์ ์์ต๋๋ค. \n
- ๋ชจ๋ธ ์ฑ๋ฅ ๋ณ๋์ฑ์ ๋ํ ์์ ์ ์ธ ์ถ์ ์น๋ฅผ ์ ๊ณตํ์ง ์์ต๋๋ค. \n
๋ฐ๋ก ์ด ์ง์ ์์ ๊ต์ฐจ ๊ฒ์ฆ์ด ๋ฑ์ฅํ์ฌ ๋ชจ๋ธ ์ฑ๋ฅ์ ์ถ์ ํ๋ ๋ ๊ฐ๋ ฅํ๊ณ ํต๊ณ์ ์ผ๋ก ๊ฑด์ ํ ๋ฐฉ๋ฒ์ ์ ๊ณตํฉ๋๋ค.
\n\n๊ต์ฐจ ๊ฒ์ฆ์ด๋? ๊ธฐ๋ณธ์ ์ธ ์์ด๋์ด
\n\n๋ณธ์ง์ ์ผ๋ก ๊ต์ฐจ ๊ฒ์ฆ์ ์ ํ๋ ๋ฐ์ดํฐ ์ํ์์ ๋จธ์ ๋ฌ๋ ๋ชจ๋ธ์ ํ๊ฐํ๋ ๋ฐ ์ฌ์ฉ๋๋ ์ฌ์ํ๋ง ์ ์ฐจ์ ๋๋ค. ์ด ์ ์ฐจ๋ ๋ฐ์ดํฐ์ ์ ๋ณด์์ ์ธ ํ์ ์งํฉ์ผ๋ก ๋ถํ ํ๊ณ , ํ ํ์ ์งํฉ("ํ๋ จ ์ธํธ")์์ ๋ถ์์ ์ํํ๋ฉฐ, ๋ค๋ฅธ ํ์ ์งํฉ("ํ ์คํธ ์ธํธ")์์ ๋ถ์์ ๊ฒ์ฆํ๋ ๊ฒ์ ํฌํจํฉ๋๋ค. ์ด ๊ณผ์ ์ ํ์ ์งํฉ์ ์ญํ ์ ๋ฐ๊ฟ๊ฐ๋ฉฐ ์ฌ๋ฌ ๋ฒ ๋ฐ๋ณต๋๋ฉฐ, ๊ทธ ๊ฒฐ๊ณผ๋ ๋ชจ๋ธ ์ฑ๋ฅ์ ๋ํ ๋ ์ ๋ขฐํ ์ ์๋ ์ถ์ ์น๋ฅผ ์์ฑํ๊ธฐ ์ํด ๊ฒฐํฉ๋ฉ๋๋ค.
\n\n๊ต์ฐจ ๊ฒ์ฆ์ ์ฃผ์ ์ด์ ์ ๋ค์๊ณผ ๊ฐ์ต๋๋ค:
\n\n- \n
- ๋ ์ ๋ขฐํ ์ ์๋ ์ฑ๋ฅ ์ถ์ ์น: ์ฌ๋ฌ ํ๋ จ-ํ ์คํธ ๋ถํ ์ ๊ฑธ์ณ ๊ฒฐ๊ณผ๋ฅผ ํ๊ท ํํจ์ผ๋ก์จ ์ฑ๋ฅ ์ถ์ ์น์ ๋ถ์ฐ์ ์ค์ฌ ๋ชจ๋ธ์ด ์ด๋ป๊ฒ ์ผ๋ฐํ๋ ์ง์ ๋ํ ๋ ์์ ์ ์ด๊ณ ์ ํํ ์ธก์ ์น๋ฅผ ์ ๊ณตํฉ๋๋ค. \n
- ๋ ๋์ ๋ฐ์ดํฐ ํ์ฉ: ๋ชจ๋ ๋ฐ์ดํฐ ํฌ์ธํธ๋ ๊ฒฐ๊ตญ ๋ค๋ฅธ ํด๋์ ๊ฑธ์ณ ํ๋ จ๊ณผ ํ ์คํธ ๋ชจ๋์ ์ฌ์ฉ๋๋ฏ๋ก ์ ํ๋ ๋ฐ์ดํฐ์ ์ ํจ์จ์ ์ผ๋ก ํ์ฉํฉ๋๋ค. \n
- ๊ณผ์ ํฉ/๊ณผ์์ ํฉ ๊ฐ์ง: ๋ชจ๋ ํด๋์์ ์ผ๊ด๋๊ฒ ๋ฎ์ ์ฑ๋ฅ์ ๊ณผ์์ ํฉ์ ๋ํ๋ผ ์ ์์ผ๋ฉฐ, ํ๋ฅญํ ํ๋ จ ์ฑ๋ฅ์ ๋ณด์ด์ง๋ง ํด๋ ์ ๋ฐ์ ๊ฑธ์ณ ๋ฎ์ ํ ์คํธ ์ฑ๋ฅ์ ๊ณผ์ ํฉ์ ์์ฌํฉ๋๋ค. \n
Scikit-learn์ ๊ต์ฐจ ๊ฒ์ฆ ํดํท
\n\nPython์ ๋จธ์ ๋ฌ๋์ ์ํ ํต์ฌ ๋ผ์ด๋ธ๋ฌ๋ฆฌ์ธ Scikit-learn์ model_selection ๋ชจ๋ ๋ด์์ ๋ค์ํ ๊ต์ฐจ ๊ฒ์ฆ ์ ๋ต์ ๊ตฌํํ๊ธฐ ์ํ ํ๋ถํ ๋๊ตฌ ์ธํธ๋ฅผ ์ ๊ณตํฉ๋๋ค. ๊ฐ์ฅ ์ผ๋ฐ์ ์ผ๋ก ์ฌ์ฉ๋๋ ํจ์๋ถํฐ ์์ํ๊ฒ ์ต๋๋ค.
cross_val_score: ๋ชจ๋ธ ์ฑ๋ฅ์ ๋ํ ๋น ๋ฅธ ๊ฐ์
\n\ncross_val_score ํจ์๋ Scikit-learn์์ ๊ต์ฐจ ๊ฒ์ฆ์ ์ํํ๋ ๊ฐ์ฅ ๊ฐ๋จํ ๋ฐฉ๋ฒ์ผ ๊ฒ์
๋๋ค. ๊ต์ฐจ ๊ฒ์ฆ์ ํตํด ์ ์๋ฅผ ํ๊ฐํ๊ณ , ๊ฐ ํด๋์ ๋ํ ์ ์ ๋ฐฐ์ด์ ๋ฐํํฉ๋๋ค.
์ฃผ์ ๋งค๊ฐ๋ณ์:
\n- \n
estimator: ๋จธ์ ๋ฌ๋ ๋ชจ๋ธ ๊ฐ์ฒด (์:LogisticRegression()). \n X: ํน์ฑ (ํ๋ จ ๋ฐ์ดํฐ). \n y: ํ๊ฒ ๋ณ์. \n cv: ๊ต์ฐจ ๊ฒ์ฆ ๋ถํ ์ ๋ต์ ๊ฒฐ์ ํฉ๋๋ค. ์ ์ (ํด๋ ์), CV ๋ถํ ๊ธฐ ๊ฐ์ฒด (์:KFold()) ๋๋ ๋ฐ๋ณต ๊ฐ๋ฅ ๊ฐ์ฒด์ผ ์ ์์ต๋๋ค. \n scoring: ํ ์คํธ ์ธํธ์์ ์์ธก์ ํ๊ฐํ๊ธฐ ์ํ ๋ฌธ์์ด (์: 'accuracy', 'f1', 'roc_auc') ๋๋ ํธ์ถ ๊ฐ๋ฅํ ๊ฐ์ฒด. \n
\nfrom sklearn.model_selection import cross_val_score\nfrom sklearn.linear_model import LogisticRegression\nfrom sklearn.datasets import load_iris\n\n# Load a sample dataset\niris = load_iris()\nX, y = iris.data, iris.target\n\n# Initialize a model\nmodel = LogisticRegression(max_iter=200)\n\n# Perform 5-fold cross-validation\nscores = cross_val_score(model, X, y, cv=5, scoring='accuracy')\n\nprint(f"Cross-validation scores: {scores}")\nprint(f"Mean accuracy: {scores.mean():.4f}")\nprint(f"Standard deviation of accuracy: {scores.std():.4f}")\n
์ด ์ถ๋ ฅ์ ๊ฐ ํด๋์ ๋ํ ์ ํ๋ ์ ์ ๋ฐฐ์ด์ ์ ๊ณตํฉ๋๋ค. ํ๊ท ๋ฐ ํ์ค ํธ์ฐจ๋ ๋ชจ๋ธ ์ฑ๋ฅ์ ์ค์ฌ ๊ฒฝํฅ๊ณผ ๋ณ๋์ฑ์ ๋ํ๋ ๋๋ค.
\n\ncross_validate: ๋ ์์ธํ ์งํ
\n\ncross_val_score๊ฐ ๋จ์ผ ์งํ๋ง ๋ฐํํ๋ ๋ฐ๋ฉด, cross_validate๋ ๋ ์์ธํ ์ ์ด๋ฅผ ์ ๊ณตํ๋ฉฐ, ๊ฐ ํด๋์ ๋ํ ํ๋ จ ์ ์, ์ ํฉ ์๊ฐ, ์ ์ ์๊ฐ์ ํฌํจํ ์งํ ๋์
๋๋ฆฌ๋ฅผ ๋ฐํํฉ๋๋ค. ์ด๋ ์ฌ๋ฌ ํ๊ฐ ์งํ ๋๋ ์ฑ๋ฅ ์๊ฐ์ ์ถ์ ํด์ผ ํ ๋ ํนํ ์ ์ฉํฉ๋๋ค.
\nfrom sklearn.model_selection import cross_validate\nfrom sklearn.linear_model import LogisticRegression\nfrom sklearn.datasets import load_iris\n\niris = load_iris()\nX, y = iris.data, iris.target\n\nmodel = LogisticRegression(max_iter=200)\n\n# Perform 5-fold cross-validation with multiple scoring metrics\nscoring = ['accuracy', 'precision_macro', 'recall_macro', 'f1_macro']\nresults = cross_validate(model, X, y, cv=5, scoring=scoring, return_train_score=True)\n\nprint("Cross-validation results:")\nfor metric_name, values in results.items():\n print(f" {metric_name}: {values}")\n print(f" Mean {metric_name}: {values.mean():.4f}")\n print(f" Std {metric_name}: {values.std():.4f}")\n
return_train_score=True ๋งค๊ฐ๋ณ์๋ ๊ณผ์ ํฉ์ ๊ฐ์งํ๋ ๋ฐ ์ค์ํฉ๋๋ค. train_score๊ฐ test_score๋ณด๋ค ํจ์ฌ ๋์ผ๋ฉด ๋ชจ๋ธ์ด ๊ณผ์ ํฉ๋์์ ๊ฐ๋ฅ์ฑ์ด ๋์ต๋๋ค.
Scikit-learn์ ์ฃผ์ ๊ต์ฐจ ๊ฒ์ฆ ์ ๋ต
\n\nScikit-learn์ ๋ค์ํ ๋ฐ์ดํฐ ํน์ฑ๊ณผ ๋ชจ๋ธ๋ง ์๋๋ฆฌ์ค์ ์ ํฉํ ์ฌ๋ฌ ์ ๋ฌธํ๋ ๊ต์ฐจ ๊ฒ์ฆ ๋ฐ๋ณต์๋ฅผ ์ ๊ณตํฉ๋๋ค. ์๋ฏธ ์๊ณ ํธํฅ๋์ง ์์ ์ฑ๋ฅ ์ถ์ ์น๋ฅผ ์ป๊ธฐ ์ํด์๋ ์ฌ๋ฐ๋ฅธ ์ ๋ต์ ์ ํํ๋ ๊ฒ์ด ์ค์ํฉ๋๋ค.
\n\n1. K-Fold ๊ต์ฐจ ๊ฒ์ฆ
\n\n์ค๋ช
: K-Fold๋ ๊ฐ์ฅ ์ผ๋ฐ์ ์ธ ๊ต์ฐจ ๊ฒ์ฆ ์ ๋ต์
๋๋ค. ๋ฐ์ดํฐ์
์ k๊ฐ์ ๋์ผํ ํฌ๊ธฐ์ ํด๋๋ก ๋๋ฉ๋๋ค. ๊ฐ ๋ฐ๋ณต์์ ํ๋์ ํด๋๋ ํ
์คํธ ์ธํธ๋ก ์ฌ์ฉ๋๊ณ , ๋๋จธ์ง k-1๊ฐ์ ํด๋๋ ํ๋ จ ์ธํธ๋ก ์ฌ์ฉ๋ฉ๋๋ค. ์ด ๊ณผ์ ์ ๊ฐ ํด๋๊ฐ ์ ํํ ํ ๋ฒ์ฉ ํ
์คํธ ์ธํธ๋ก ์ฌ์ฉ๋๋๋ก k๋ฒ ๋ฐ๋ณต๋ฉ๋๋ค.
์ฌ์ฉ ์๊ธฐ: ๋ฐ์ดํฐ ํฌ์ธํธ๊ฐ ๋ ๋ฆฝ์ ์ด๊ณ ๋์ผํ๊ฒ ๋ถํฌ๋(i.i.d.) ๋ง์ ํ์ค ๋ถ๋ฅ ๋ฐ ํ๊ท ์์ ์ ์ ํฉํ ๋ฒ์ฉ์ ์ธ ์ ํ์ ๋๋ค.
\n\n๊ณ ๋ ค ์ฌํญ:
\n- \n
- ์ผ๋ฐ์ ์ผ๋ก
k๋ 5 ๋๋ 10์ผ๋ก ์ค์ ๋ฉ๋๋ค.k๊ฐ ๋์์๋ก ํธํฅ์ด ์ ์ง๋ง ๊ณ์ฐ ๋น์ฉ์ด ๋ ๋ง์ด ๋๋ ์ถ์ ์น๊ฐ ๋์ต๋๋ค. \n - ๋ถ๊ท ํ ๋ฐ์ดํฐ์ ์ ๊ฒฝ์ฐ ๋ฌธ์ ๊ฐ ๋ ์ ์์ต๋๋ค. ์ผ๋ถ ํด๋์๋ ์์ ํด๋์ค์ ์ํ์ด ๊ฑฐ์ ์๊ฑฐ๋ ์ ํ ์์ ์ ์๊ธฐ ๋๋ฌธ์ ๋๋ค. \n
\nfrom sklearn.model_selection import KFold\nimport numpy as np\n\nX = np.array([[1, 2], [3, 4], [1, 2], [3, 4], [1, 2], [3, 4]])\ny = np.array([0, 1, 0, 1, 0, 1])\n\nkf = KFold(n_splits=3, shuffle=True, random_state=42)\n\nprint("K-Fold Cross-validation splits:")\nfor i, (train_index, test_index) in enumerate(kf.split(X)):\n print(f" Fold {i+1}:")\n print(f" TRAIN: {train_index}, TEST: {test_index}")\n print(f" Train data X: {X[train_index]}, y: {y[train_index]}")\n print(f" Test data X: {X[test_index]}, y: {y[test_index]}")\n
shuffle=True ๋งค๊ฐ๋ณ์๋ ๋ฐ์ดํฐ๋ฅผ ๋ถํ ํ๊ธฐ ์ ์ ๋ฌด์์ํํ๋ ๋ฐ ์ค์ํฉ๋๋ค. ํนํ ๋ฐ์ดํฐ์ ๊ณ ์ ํ ์์๊ฐ ์๋ ๊ฒฝ์ฐ ๋์ฑ ๊ทธ๋ ์ต๋๋ค. random_state๋ ์
ํ๋ง์ ์ฌํ์ฑ์ ๋ณด์ฅํฉ๋๋ค.
2. ๊ณ์ธต๋ณ K-Fold ๊ต์ฐจ ๊ฒ์ฆ
\n\n์ค๋ช : ์ด๋ K-Fold์ ๋ณํ์ผ๋ก, ํนํ ๋ถ๊ท ํ ๋ฐ์ดํฐ์ ์ด ์๋ ๋ถ๋ฅ ์์ ์ ์ํด ์ค๊ณ๋์์ต๋๋ค. ์ด๋ ๊ฐ ํด๋๊ฐ ์ ์ฒด ์ธํธ์ ๋์ผํ ๊ฐ ํ๊ฒ ํด๋์ค ์ํ์ ๋ฐฑ๋ถ์จ์ ๋๋ต์ ์ผ๋ก ๊ฐ๋๋ก ๋ณด์ฅํฉ๋๋ค. ์ด๋ ํด๋๊ฐ ์์ ํด๋์ค ์ํ์ด ์ ํ ์๋ ์ํ๊ฐ ๋์ด ๋ชจ๋ธ ํ๋ จ ๋๋ ํ ์คํธ๊ฐ ์ ๋๋ก ์ด๋ฃจ์ด์ง์ง ์๋ ๊ฒ์ ๋ฐฉ์งํฉ๋๋ค.
\n\n์ฌ์ฉ ์๊ธฐ: ๋ถ๋ฅ ๋ฌธ์ ์ ํ์์ ์ด๋ฉฐ, ํนํ ์๋ฃ ์ง๋จ(์: ํฌ๊ท ์ง๋ณ ํ์ง), ์ฌ๊ธฐ ํ์ง ๋๋ ์ด์ ๊ฐ์ง์์ ํํ ๋ณผ ์ ์๋ ๋ถ๊ท ํ ํด๋์ค ๋ถํฌ๋ฅผ ๋ค๋ฃฐ ๋ ๋์ฑ ๊ทธ๋ ์ต๋๋ค.
\n\n
\nfrom sklearn.model_selection import StratifiedKFold\n\nX = np.array([[1, 2], [3, 4], [1, 2], [3, 4], [1, 2], [3, 4], [5,6], [7,8], [9,10], [11,12]])\ny_imbalanced = np.array([0, 0, 0, 0, 0, 0, 1, 1, 1, 1]) # 60% class 0, 40% class 1\n\nskf = StratifiedKFold(n_splits=3, shuffle=True, random_state=42)\n\nprint("Stratified K-Fold Cross-validation splits:")\nfor i, (train_index, test_index) in enumerate(skf.split(X, y_imbalanced)):\n print(f" Fold {i+1}:")\n print(f" TRAIN: {train_index}, TEST: {test_index}")\n print(f" Train y distribution: {np.bincount(y_imbalanced[train_index])}")\n print(f" Test y distribution: {np.bincount(y_imbalanced[test_index])}")\n
np.bincount๊ฐ ๊ฐ ํด๋์ ํ๋ จ ์ธํธ์ ํ
์คํธ ์ธํธ ๋ชจ๋์์ ์ ์ฌํ ํด๋์ค ๋น์จ(์: n_splits๋ฅผ ๊ณ ๋ คํ ๋ 60/40 ๋ถํ ๋๋ ๊ฐ๋ฅํ ํ ๊ฐ๊น๊ฒ)์ ์ ์งํ๋ ๋ฐฉ๋ฒ์ ํ์ธํ์ธ์.
3. Leave-One-Out Cross-Validation (LOOCV)
\n\n์ค๋ช
: LOOCV๋ K-Fold์ ๊ทน๋จ์ ์ธ ๊ฒฝ์ฐ๋ก, k๊ฐ ์ํ ์(n)์ ๊ฐ์ต๋๋ค. ๊ฐ ํด๋์ ๋ํด ํ๋์ ์ํ์ด ํ
์คํธ ์ธํธ๋ก ์ฌ์ฉ๋๊ณ , ๋๋จธ์ง n-1๊ฐ์ ์ํ์ ํ๋ จ์ ์ฌ์ฉ๋ฉ๋๋ค. ์ฆ, ๋ชจ๋ธ์ n๋ฒ ํ๋ จ๋๊ณ ํ๊ฐ๋ฉ๋๋ค.
์ฌ์ฉ ์๊ธฐ:
\n- \n
- ๊ฐ ๋ฐ๋ณต์ ์ํ ํ๋ จ ๋ฐ์ดํฐ๋ฅผ ์ต๋ํํ๋ ๊ฒ์ด ์ค์ํ ๋งค์ฐ ์์ ๋ฐ์ดํฐ์ ์ ์ ํฉํฉ๋๋ค. \n
- ๋ชจ๋ธ ์ฑ๋ฅ์ ๋ํ ๊ฑฐ์ ํธํฅ ์๋ ์ถ์ ์น๋ฅผ ์ ๊ณตํฉ๋๋ค. \n
๊ณ ๋ ค ์ฌํญ:
\n- \n
- ๋ชจ๋ธ์
n๋ฒ ํ๋ จํด์ผ ํ๋ฏ๋ก ๋๊ท๋ชจ ๋ฐ์ดํฐ์ ์๋ ๊ณ์ฐ ๋น์ฉ์ด ๋งค์ฐ ๋ง์ด ๋ญ๋๋ค. \n - ํ ์คํธ ์ธํธ๊ฐ ๋๋ฌด ์๊ธฐ ๋๋ฌธ์ ๋ฐ๋ณต ๊ฐ ์ฑ๋ฅ ์ถ์ ์น์ ๋ถ์ฐ์ด ๋์ต๋๋ค. \n
\nfrom sklearn.model_selection import LeaveOneOut\n\nX = np.array([[1, 2], [3, 4], [5, 6], [7, 8]])\ny = np.array([0, 1, 0, 1])\n\nloo = LeaveOneOut()\n\nprint("Leave-One-Out Cross-validation splits:")\nfor i, (train_index, test_index) in enumerate(loo.split(X)):\n print(f" Iteration {i+1}: TRAIN: {train_index}, TEST: {test_index}")\n
4. ShuffleSplit ๋ฐ StratifiedShuffleSplit
\n\n์ค๋ช
: ๊ฐ ์ํ์ด ํ
์คํธ ์ธํธ์ ์ ํํ ํ ๋ฒ ๋ํ๋๋ ๊ฒ์ ๋ณด์ฅํ๋ K-Fold์ ๋ฌ๋ฆฌ, ShuffleSplit์ n_splits๊ฐ์ ๋ฌด์์ ํ๋ จ/ํ
์คํธ ๋ถํ ์ ๊ทธ๋ฆฝ๋๋ค. ๊ฐ ๋ถํ ์ ๋ํด ๋ฐ์ดํฐ์ ์ผ๋ถ๋ ํ๋ จ์ ์ํด ๋ฌด์์๋ก ์ ํ๋๊ณ , ๋ค๋ฅธ (๋ถ๋ฆฌ๋) ์ผ๋ถ๋ ํ
์คํธ๋ฅผ ์ํด ์ ํ๋ฉ๋๋ค. ์ด๋ ๋ฐ๋ณต์ ์ธ ๋ฌด์์ ์๋ธ์ํ๋ง์ ํ์ฉํฉ๋๋ค.
์ฌ์ฉ ์๊ธฐ:
\n- \n
- K-Fold์ ํด๋ ์(
k)๊ฐ ์ ํ์ ์ด์ง๋ง ์ฌ์ ํ ์ฌ๋ฌ ๋ ๋ฆฝ์ ์ธ ๋ถํ ์ ์ํ ๋. \n - K-Fold๊ฐ ๊ณ์ฐ ์ง์ฝ์ ์ผ ์ ์๋ ๋๊ท๋ชจ ๋ฐ์ดํฐ์
๋๋ ๋จ์ํ
1/k์ด์์ผ๋ก ํ ์คํธ ์ธํธ ํฌ๊ธฐ๋ฅผ ๋ ์ ์ดํ๊ณ ์ถ์ ๋ ์ ์ฉํฉ๋๋ค. \n StratifiedShuffleSplit์ ๊ฐ ๋ถํ ์์ ํด๋์ค ๋ถํฌ๋ฅผ ์ ์งํ๋ฏ๋ก ๋ถ๊ท ํ ๋ฐ์ดํฐ๊ฐ ์๋ ๋ถ๋ฅ์ ์ ํธ๋๋ ์ ํ์ ๋๋ค. \n
๊ณ ๋ ค ์ฌํญ: ๋ชจ๋ ์ํ์ด ์ ์ด๋ ํ๋์ ๋ถํ ์์ ํ ์คํธ ์ธํธ ๋๋ ํ๋ จ ์ธํธ์ ํฌํจ๋๋ค๋ ๋ณด์ฅ์ ์์ง๋ง, ๋ง์ ๋ถํ ์์๋ ์ด๋ฌํ ๊ฐ๋ฅ์ฑ์ด ์ค์ด๋ญ๋๋ค.
\n\n
\nfrom sklearn.model_selection import ShuffleSplit, StratifiedShuffleSplit\n\nX = np.array([[1, 2], [3, 4], [1, 2], [3, 4], [1, 2], [3, 4], [5,6], [7,8], [9,10], [11,12]])\ny = np.array([0, 0, 0, 0, 0, 1, 1, 1, 1, 1]) # Imbalanced data for StratifiedShuffleSplit\n\n# ShuffleSplit example\nss = ShuffleSplit(n_splits=5, test_size=0.3, random_state=42)\nprint("ShuffleSplit Cross-validation splits:")\nfor i, (train_index, test_index) in enumerate(ss.split(X)):\n print(f" Split {i+1}: TRAIN: {train_index}, TEST: {test_index}")\n\n# StratifiedShuffleSplit example\nsss = StratifiedShuffleSplit(n_splits=5, test_size=0.3, random_state=42)\nprint("\nStratifiedShuffleSplit Cross-validation splits (y distribution maintained):")\nfor i, (train_index, test_index) in enumerate(sss.split(X, y)):\n print(f" Split {i+1}:")\n print(f" TRAIN: {train_index}, TEST: {test_index}")\n print(f" Train y distribution: {np.bincount(y[train_index])}")\n print(f" Test y distribution: {np.bincount(y[test_index])}")\n
5. ์๊ณ์ด ๊ต์ฐจ ๊ฒ์ฆ (TimeSeriesSplit)
\n\n์ค๋ช : ํ์ค ๊ต์ฐจ ๊ฒ์ฆ ๋ฐฉ๋ฒ์ ๋ฐ์ดํฐ ํฌ์ธํธ๊ฐ ๋ ๋ฆฝ์ ์ด๋ผ๊ณ ๊ฐ์ ํฉ๋๋ค. ๊ทธ๋ฌ๋ ์๊ณ์ด ๋ฐ์ดํฐ์์๋ ๊ด์ธก์น๊ฐ ์์๋๋ก ๋ฐฐ์ด๋์ด ์์ผ๋ฉฐ ์ข ์ข ์๊ฐ์ ์ข ์์ฑ์ ๋ํ๋ ๋๋ค. ์๊ณ์ด ๋ฐ์ดํฐ๋ฅผ ์ ํ๋งํ๊ฑฐ๋ ๋ฌด์์๋ก ๋ถํ ํ๋ฉด ๋ฐ์ดํฐ ์ ์ถ๋ก ์ด์ด์ ธ ๋ชจ๋ธ์ด ๋ฏธ๋ ๋ฐ์ดํฐ๋ฅผ ํ๋ จํ์ฌ ๊ณผ๊ฑฐ ๋ฐ์ดํฐ๋ฅผ ์์ธกํ๊ฒ ๋๋ฏ๋ก ์ง๋์น๊ฒ ๋๊ด์ ์ด๊ณ ๋นํ์ค์ ์ธ ์ฑ๋ฅ ์ถ์ ์น๊ฐ ๋์ต๋๋ค.
\n\nTimeSeriesSplit์ ํ
์คํธ ์ธํธ๊ฐ ํญ์ ํ๋ จ ์ธํธ ๋ค์ ์ค๋ ํ๋ จ/ํ
์คํธ ๋ถํ ์ ์ ๊ณตํ์ฌ ์ด ๋ฌธ์ ๋ฅผ ํด๊ฒฐํฉ๋๋ค. ๋ฐ์ดํฐ๋ฅผ ํ๋ จ ์ธํธ์ ๊ทธ ์ดํ์ ํ
์คํธ ์ธํธ๋ก ๋ถํ ํ ๋ค์, ํ๋ จ ์ธํธ๋ฅผ ์ ์ง์ ์ผ๋ก ํ์ฅํ๊ณ ํ
์คํธ ์ธํธ๋ฅผ ์๊ฐ์ ์ผ๋ก ์์ผ๋ก ์ด๋์ํค๋ ๋ฐฉ์์ผ๋ก ์๋ํฉ๋๋ค.
์ฌ์ฉ ์๊ธฐ: ์๊ณ์ด ์์ธก ๋๋ ๊ด์ธก์น์ ์๊ฐ ์์๋ฅผ ๋ณด์กดํด์ผ ํ๋ ๋ชจ๋ ์์ฐจ ๋ฐ์ดํฐ์๋ง ์ฌ์ฉ๋ฉ๋๋ค.
\n\n๊ณ ๋ ค ์ฌํญ: ํ๋ จ ์ธํธ๋ ๊ฐ ๋ถํ ๋ง๋ค ์ปค์ง๋ฏ๋ก ์ฑ๋ฅ์ด ๋ค์ํด์ง ์ ์์ผ๋ฉฐ, ์ด๊ธฐ ํ๋ จ ์ธํธ๋ ์๋นํ ์์ ์ ์์ต๋๋ค.
\n\n
\nfrom sklearn.model_selection import TimeSeriesSplit\nimport pandas as pd\n\n# Simulate time series data\ndates = pd.to_datetime(pd.date_range(start='2023-01-01', periods=100, freq='D'))\nX_ts = np.arange(100).reshape(-1, 1)\ny_ts = np.sin(np.arange(100) / 10) + np.random.randn(100) * 0.1 # Some time-dependent target\n\ntscv = TimeSeriesSplit(n_splits=5)\n\nprint("Time Series Cross-validation splits:")\nfor i, (train_index, test_index) in enumerate(tscv.split(X_ts)):\n print(f" Fold {i+1}:")\n print(f" TRAIN indices: {train_index[0]} to {train_index[-1]}")\n print(f" TEST indices: {test_index[0]} to {test_index[-1]}")\n # Verify that test_index always starts after train_index ends\n assert train_index[-1] < test_index[0]\n
์ด ๋ฐฉ๋ฒ์ ๋ชจ๋ธ์ด ํญ์ ํ๋ จ๋ ๋ฐ์ดํฐ์ ๋นํด ๋ฏธ๋ ๋ฐ์ดํฐ๋ก ํ๊ฐ๋๋๋ก ๋ณด์ฅํ์ฌ, ์๊ฐ ์ข ์์ ์ธ ๋ฌธ์ ์ ๋ํ ์ค์ ๋ฐฐํฌ ์๋๋ฆฌ์ค๋ฅผ ๋ชจ๋ฐฉํฉ๋๋ค.
\n\n6. ๊ทธ๋ฃน ๊ต์ฐจ ๊ฒ์ฆ (GroupKFold, LeaveOneGroupOut)
\n\n์ค๋ช : ์ผ๋ถ ๋ฐ์ดํฐ์ ์์๋ ์ํ์ด ์์ ํ ๋ ๋ฆฝ์ ์ด์ง ์์ ์ ์์ผ๋ฉฐ, ํน์ ๊ทธ๋ฃน์ ์ํ ์ ์์ต๋๋ค. ์๋ฅผ ๋ค์ด, ๋์ผํ ํ์์ ์ฌ๋ฌ ์๋ฃ ์ธก์ ๊ฐ, ๋์ผํ ์ผ์์ ์ฌ๋ฌ ๊ด์ธก๊ฐ ๋๋ ๋์ผํ ๊ณ ๊ฐ์ ์ฌ๋ฌ ๊ธ์ต ๊ฑฐ๋ ๋ฑ์ด ์์ต๋๋ค. ์ด๋ฌํ ๊ทธ๋ฃน์ด ํ๋ จ ์ธํธ์ ํ ์คํธ ์ธํธ๋ก ๋ถํ ๋๋ฉด ๋ชจ๋ธ์ด ๊ทธ๋ฃน๋ณ ํจํด์ ํ์ตํ๊ณ ์๋ก์ด, ๋ณด์ง ๋ชปํ ๊ทธ๋ฃน์ ์ผ๋ฐํํ๋ ๋ฐ ์คํจํ ์ ์์ต๋๋ค. ์ด๋ ๋ฐ์ดํฐ ์ ์ถ์ ํ ํํ์ ๋๋ค.
\n\n๊ทธ๋ฃน ๊ต์ฐจ ๊ฒ์ฆ ์ ๋ต์ ๋จ์ผ ๊ทธ๋ฃน์ ๋ชจ๋ ๋ฐ์ดํฐ ํฌ์ธํธ๊ฐ ํ๋ จ ์ธํธ์๋ง ๋ํ๋๊ฑฐ๋ ํ ์คํธ ์ธํธ์๋ง ๋ํ๋๋๋ก ํ์ฌ ๋ ๋ชจ๋์ ๋ํ๋์ง ์๋๋ก ๋ณด์ฅํฉ๋๋ค.
\n\n์ฌ์ฉ ์๊ธฐ: ์ข ๋จ ์ฐ๊ตฌ, ์ฌ๋ฌ ์ฅ์น์ ์ผ์ ๋ฐ์ดํฐ ๋๋ ๊ณ ๊ฐ๋ณ ํ๋ ๋ชจ๋ธ๋ง๊ณผ ๊ฐ์ด ๋ฐ์ดํฐ์ ํด๋ ๊ฐ์ ๋ถํ ๋ ๊ฒฝ์ฐ ํธํฅ์ ์ ๋ฐํ ์ ์๋ ๊ณ ์ ํ ๊ทธ๋ฃน์ด ์๋ ๊ฒฝ์ฐ.
\n\n๊ณ ๋ ค ์ฌํญ: ๊ฐ ์ํ์ ๋ํ ๊ทธ๋ฃน ์๋ณ์๋ฅผ ์ง์ ํ๋ 'groups' ๋ฐฐ์ด์ .split() ๋ฉ์๋์ ์ ๋ฌํด์ผ ํฉ๋๋ค.
\nfrom sklearn.model_selection import GroupKFold\n\nX = np.array([[1, 2], [3, 4], [5, 6], [7, 8], [9, 10], [11, 12], [13, 14], [15, 16]])\ny = np.array([0, 1, 0, 1, 0, 1, 0, 1])\n# Two groups: samples 0-3 belong to Group A, samples 4-7 belong to Group B\ngroups = np.array(['A', 'A', 'A', 'A', 'B', 'B', 'B', 'B'])\n\ngkf = GroupKFold(n_splits=2) # We'll use 2 splits to clearly separate groups\n\nprint("Group K-Fold Cross-validation splits:")\nfor i, (train_index, test_index) in enumerate(gkf.split(X, y, groups)):\n print(f" Fold {i+1}:")\n print(f" TRAIN indices: {train_index}, GROUPS: {groups[train_index]}")\n print(f" TEST indices: {test_index}, GROUPS: {groups[test_index]}")\n # Verify that no group appears in both train and test sets for a single fold\n assert len(set(groups[train_index]).intersection(set(groups[test_index]))) == 0\n
๋ค๋ฅธ ๊ทธ๋ฃน ์ธ์ ์ ๋ต์๋ LeaveOneGroupOut (๊ฐ ๊ณ ์ ๊ทธ๋ฃน์ด ํ ๋ฒ ํ
์คํธ ์ธํธ๋ฅผ ํ์ฑํจ) ๋ฐ LeavePGroupsOut (ํ
์คํธ ์ธํธ์ P๊ฐ์ ๊ทธ๋ฃน์ ๋จ๊น)์ด ์์ต๋๋ค.
๊ต์ฐจ ๊ฒ์ฆ์ ํตํ ๊ณ ๊ธ ๋ชจ๋ธ ์ ํ
\n\n๊ต์ฐจ ๊ฒ์ฆ์ ๋จ์ผ ๋ชจ๋ธ์ ํ๊ฐํ๋ ๊ฒ๋ฟ๋ง ์๋๋ผ ์ต์์ ๋ชจ๋ธ์ ์ ํํ๊ณ ํ์ดํผํ๋ผ๋ฏธํฐ๋ฅผ ํ๋ํ๋ ๋ฐ์๋ ํ์์ ์ ๋๋ค.
\n\nGridSearchCV ๋ฐ RandomizedSearchCV๋ฅผ ์ด์ฉํ ํ์ดํผํ๋ผ๋ฏธํฐ ํ๋
\n\n๋จธ์ ๋ฌ๋ ๋ชจ๋ธ์๋ ๋ฐ์ดํฐ๋ก๋ถํฐ ํ์ต๋์ง ์๊ณ ํ๋ จ ์ ์ ์ค์ ํด์ผ ํ๋ ํ์ดํผํ๋ผ๋ฏธํฐ๊ฐ ์ข
์ข
์์ต๋๋ค. ์ด๋ฌํ ํ์ดํผํ๋ผ๋ฏธํฐ์ ์ต์ ๊ฐ์ ์ผ๋ฐ์ ์ผ๋ก ๋ฐ์ดํฐ์
์ ๋ฐ๋ผ ๋ค๋ฆ
๋๋ค. Scikit-learn์ GridSearchCV์ RandomizedSearchCV๋ ๊ต์ฐจ ๊ฒ์ฆ์ ํ์ฉํ์ฌ ํ์ดํผํ๋ผ๋ฏธํฐ์ ์ต์์ ์กฐํฉ์ ์ฒด๊ณ์ ์ผ๋ก ๊ฒ์ํฉ๋๋ค.
- \n
GridSearchCV: ์ง์ ๋ ๋งค๊ฐ๋ณ์ ๊ทธ๋ฆฌ๋๋ฅผ ์ฒ ์ ํ ๊ฒ์ํ์ฌ ๊ต์ฐจ ๊ฒ์ฆ์ ์ฌ์ฉํ์ฌ ๊ฐ๋ฅํ ๋ชจ๋ ์กฐํฉ์ ํ๊ฐํฉ๋๋ค. ๊ทธ๋ฆฌ๋ ๋ด์์ ์ต์์ ์กฐํฉ์ ์ฐพ๋ ๊ฒ์ ๋ณด์ฅํ์ง๋ง, ํฐ ๊ทธ๋ฆฌ๋์๋ ๊ณ์ฐ ๋น์ฉ์ด ๋ง์ด ๋ค ์ ์์ต๋๋ค. \n RandomizedSearchCV: ์ง์ ๋ ๋ถํฌ์์ ๊ณ ์ ๋ ์์ ๋งค๊ฐ๋ณ์ ์ค์ ์ ์ํ๋งํฉ๋๋ค. ๋ชจ๋ ์กฐํฉ์ ์๋ํ์ง ์์ผ๋ฏ๋ก ํฐ ๊ฒ์ ๊ณต๊ฐ์ ๋ํดGridSearchCV๋ณด๋ค ํจ์จ์ ์ด๋ฉฐ ์ข ์ข ๋ ์งง์ ์๊ฐ์ ์ข์ ํด๊ฒฐ์ฑ ์ ์ฐพ์ต๋๋ค. \n
\nfrom sklearn.model_selection import GridSearchCV\nfrom sklearn.svm import SVC\nfrom sklearn.datasets import load_breast_cancer\n\n# Load a sample dataset\ncancer = load_breast_cancer()\nX, y = cancer.data, cancer.target\n\n# Define the model and parameter grid\nmodel = SVC()\nparam_grid = {\n 'C': [0.1, 1, 10],\n 'kernel': ['linear', 'rbf']\n}\n\n# Perform GridSearchCV with 5-fold cross-validation\ngrid_search = GridSearchCV(estimator=model, param_grid=param_grid, cv=5, scoring='accuracy', n_jobs=-1)\ngrid_search.fit(X, y)\n\nprint(f"Best parameters: {grid_search.best_params_}")\nprint(f"Best cross-validation accuracy: {grid_search.best_score_:.4f}")\n
GridSearchCV์ RandomizedSearchCV๋ ๋ชจ๋ cv ๋งค๊ฐ๋ณ์๋ฅผ ํ์ฉํ์ฌ ์ด์ ์ ๋
ผ์๋ ๊ต์ฐจ ๊ฒ์ฆ ๋ฐ๋ณต์(์: ๋ถ๊ท ํ ๋ถ๋ฅ ์์
์ ์ํ StratifiedKFold)๋ฅผ ์ง์ ํ ์ ์์ต๋๋ค.
์ค์ฒฉ ๊ต์ฐจ ๊ฒ์ฆ: ์ง๋์น๊ฒ ๋๊ด์ ์ธ ์ถ์ ๋ฐฉ์ง
\n\nํ์ดํผํ๋ผ๋ฏธํฐ ํ๋์ ์ํด ๊ต์ฐจ ๊ฒ์ฆ(์: GridSearchCV ์ฌ์ฉ)์ ์ฌ์ฉํ ๋ค์, ์ฐพ์ ์ต์์ ๋งค๊ฐ๋ณ์๋ฅผ ์ฌ์ฉํ์ฌ ์ธ๋ถ ํ
์คํธ ์ธํธ์์ ๋ชจ๋ธ์ ํ๊ฐํ ๋, ์ฌ์ ํ ๋ชจ๋ธ ์ฑ๋ฅ์ ๋ํ ์ง๋์น๊ฒ ๋๊ด์ ์ธ ์ถ์ ์น๋ฅผ ์ป์ ์ ์์ต๋๋ค. ์ด๋ ํ์ดํผํ๋ผ๋ฏธํฐ ์ ํ ์์ฒด๊ฐ ๋ฐ์ดํฐ ์ ์ถ์ ํ ํํ๋ฅผ ๋์
ํ๊ธฐ ๋๋ฌธ์
๋๋ค. ์ฆ, ํ์ดํผํ๋ผ๋ฏธํฐ๋ ์ ์ฒด ํ๋ จ ๋ฐ์ดํฐ(๋ด๋ถ ๋ฃจํ์ ๊ฒ์ฆ ํด๋ ํฌํจ)๋ฅผ ๊ธฐ๋ฐ์ผ๋ก ์ต์ ํ๋์ด ๋ชจ๋ธ์ด ํ
์คํธ ์ธํธ์ ํน์ฑ์ ์ฝ๊ฐ "์ธ์ง"ํ๊ฒ ๋ฉ๋๋ค.
์ค์ฒฉ ๊ต์ฐจ ๊ฒ์ฆ์ ์ด๋ฅผ ํด๊ฒฐํ๋ ๋ ์๊ฒฉํ ์ ๊ทผ ๋ฐฉ์์ ๋๋ค. ๋ ๊ฐ์ ๊ต์ฐจ ๊ฒ์ฆ ๊ณ์ธต์ ํฌํจํฉ๋๋ค:
\n\n- \n
- ์ธ๋ถ ๋ฃจํ: ์ผ๋ฐ ๋ชจ๋ธ ํ๊ฐ๋ฅผ ์ํด ๋ฐ์ดํฐ์ ์ K๊ฐ์ ํด๋๋ก ๋๋๋๋ค. \n
- ๋ด๋ถ ๋ฃจํ: ์ธ๋ถ ๋ฃจํ์ ๊ฐ ํ๋ จ ํด๋์ ๋ํด, ์ต์์ ํ์ดํผํ๋ผ๋ฏธํฐ๋ฅผ ์ฐพ๊ธฐ ์ํด ๋ ๋ค๋ฅธ ๊ต์ฐจ ๊ฒ์ฆ ๋ผ์ด๋(์:
GridSearchCV์ฌ์ฉ)๋ฅผ ์ํํฉ๋๋ค. ๊ทธ๋ฐ ๋ค์ ๋ชจ๋ธ์ ์ด๋ฌํ ์ต์ ํ์ดํผํ๋ผ๋ฏธํฐ๋ฅผ ์ฌ์ฉํ์ฌ ์ด ์ธ๋ถ ํ๋ จ ํด๋์์ ํ๋ จ๋ฉ๋๋ค. \n - ํ๊ฐ: ํ๋ จ๋ ๋ชจ๋ธ(์ต์์ ๋ด๋ถ ๋ฃจํ ํ์ดํผํ๋ผ๋ฏธํฐ ํฌํจ)์ ํด๋น ์ธ๋ถ ํ ์คํธ ํด๋์์ ํ๊ฐ๋ฉ๋๋ค. \n
์ด๋ฌํ ๋ฐฉ์์ผ๋ก ํ์ดํผํ๋ผ๋ฏธํฐ๋ ๊ฐ ์ธ๋ถ ํด๋์ ๋ํด ๋ ๋ฆฝ์ ์ผ๋ก ์ต์ ํ๋์ด, ๋ณด์ง ๋ชปํ ๋ฐ์ดํฐ์ ๋ํ ๋ชจ๋ธ์ ์ผ๋ฐํ ์ฑ๋ฅ์ ๋ํ ์ง์ ์ผ๋ก ํธํฅ ์๋ ์ถ์ ์น๋ฅผ ์ ๊ณตํฉ๋๋ค. ๊ณ์ฐ ์ง์ฝ์ ์ด์ง๋ง, ํ์ดํผํ๋ผ๋ฏธํฐ ํ๋์ด ํฌํจ๋ ๋ ์ค์ฒฉ ๊ต์ฐจ ๊ฒ์ฆ์ ๊ฐ๋ ฅํ ๋ชจ๋ธ ์ ํ์ ์ํ ๊ณจ๋ ์คํ ๋ค๋์ ๋๋ค.
\n\n๊ธ๋ก๋ฒ ์ฒญ์ค์ ์ํ ๋ชจ๋ฒ ์ฌ๋ก ๋ฐ ๊ณ ๋ ค ์ฌํญ
\n\n๊ต์ฐจ ๊ฒ์ฆ์ ํจ๊ณผ์ ์ผ๋ก ์ ์ฉํ๋ ค๋ฉด ํนํ ๋ค์ํ ๊ธ๋ก๋ฒ ์ปจํ ์คํธ์ ๋ค์ํ ๋ฐ์ดํฐ์ ์ผ๋ก ์์ ํ ๋ ์ ์คํ ๊ณ ๋ ค๊ฐ ํ์ํฉ๋๋ค.
\n\n- \n
- ์ฌ๋ฐ๋ฅธ ์ ๋ต ์ ํ: ํญ์ ๋ฐ์ดํฐ์ ๊ณ ์ ํ ์์ฑ์ ๊ณ ๋ คํ์ญ์์ค. ์๊ฐ ์ข ์์ ์ธ๊ฐ์? ๊ทธ๋ฃนํ๋ ๊ด์ธก์น๊ฐ ์๋์? ํด๋์ค ๋ ์ด๋ธ์ด ๋ถ๊ท ํ์ธ๊ฐ์? ์ด๋ ํ๋ฆผ์์ด ๊ฐ์ฅ ์ค์ํ ๊ฒฐ์ ์ ๋๋ค. ์๋ชป๋ ์ ํ(์: ์๊ณ์ด์ K-Fold ์ฌ์ฉ)์ ์ง๋ฆฌ์ ์์น๋ ๋ฐ์ดํฐ์ ์ถ์ฒ์ ๊ด๊ณ์์ด ์๋ชป๋ ๊ฒฐ๊ณผ๋ก ์ด์ด์ง ์ ์์ต๋๋ค. \n
- ๋ฐ์ดํฐ์
ํฌ๊ธฐ ๋ฐ ๊ณ์ฐ ๋น์ฉ: ๋๊ท๋ชจ ๋ฐ์ดํฐ์
์ ์ข
์ข
๊ณ์ฐ ๋ฆฌ์์ค๋ฅผ ๊ด๋ฆฌํ๊ธฐ ์ํด ๋ ์ ์ ํด๋(์: 10-fold ๋๋ LOOCV ๋์ 5-fold) ๋๋
ShuffleSplit๊ณผ ๊ฐ์ ๋ฉ์๋๋ฅผ ํ์๋ก ํฉ๋๋ค. ๋ถ์ฐ ์ปดํจํ ํ๋ซํผ ๋ฐ ํด๋ผ์ฐ๋ ์๋น์ค(AWS, Azure, Google Cloud ๋ฑ)๋ ์ ์ธ๊ณ์ ์ผ๋ก ์ ๊ทผ ๊ฐ๋ฅํ๋ฉฐ ์ง์ค์ ์ธ ๊ต์ฐจ ๊ฒ์ฆ ์์ ์ ์ฒ๋ฆฌํ๋ ๋ฐ ๋์์ด ๋ ์ ์์ต๋๋ค. \n - ์ฌํ์ฑ: ๊ต์ฐจ ๊ฒ์ฆ ๋ถํ ๊ธฐ(์:
KFold(..., random_state=42))์ ํญ์random_state๋ฅผ ์ค์ ํ์ญ์์ค. ์ด๋ ๋ค๋ฅธ ์ฌ๋๋ค์ด ๊ฒฐ๊ณผ๋ฅผ ์ฌํํ ์ ์๋๋ก ๋ณด์ฅํ์ฌ ๊ตญ์ ํ ๊ฐ์ ํฌ๋ช ์ฑ๊ณผ ํ์ ์ ์ด์งํฉ๋๋ค. \n - ๊ฒฐ๊ณผ ํด์: ๋จ์ํ ํ๊ท ์ ์ ์ด์์ ์ดํด๋ณด์ญ์์ค. ๊ต์ฐจ ๊ฒ์ฆ ์ ์์ ํ์ค ํธ์ฐจ๋ ๋ชจ๋ธ ์ฑ๋ฅ์ ๋ณ๋์ฑ์ ๋ํ๋ ๋๋ค. ๋์ ํ์ค ํธ์ฐจ๋ ๋ชจ๋ธ ์ฑ๋ฅ์ด ํน์ ๋ฐ์ดํฐ ๋ถํ ์ ๋ฏผ๊ฐํ๋ค๋ ๊ฒ์ ์์ฌํ ์ ์์ผ๋ฉฐ, ์ด๋ ์ฐ๋ ค ์ฌํญ์ด ๋ ์ ์์ต๋๋ค. \n
- ๋๋ฉ์ธ ์ง์์ ์ค์์ฑ: ๋ฐ์ดํฐ์ ์ถ์ฒ์ ํน์ฑ์ ์ดํดํ๋ ๊ฒ์ด ๊ฐ์ฅ ์ค์ํฉ๋๋ค. ์๋ฅผ ๋ค์ด, ๊ณ ๊ฐ ๋ฐ์ดํฐ๊ฐ ๋ค๋ฅธ ์ง๋ฆฌ์ ์ง์ญ์์ ์๋ค๋ ๊ฒ์ ์๋ฉด ์ง์ญ ํจํด์ด ๊ฐํ ๊ฒฝ์ฐ ๊ทธ๋ฃน ๊ธฐ๋ฐ ๊ต์ฐจ ๊ฒ์ฆ์ด ํ์ํ ์ ์์ต๋๋ค. ๋ฐ์ดํฐ ์ดํด์ ๋ํ ๊ธ๋ก๋ฒ ํ์ ์ด ์ฌ๊ธฐ์์ ํต์ฌ์ ๋๋ค. \n
- ์ค๋ฆฌ์ ๊ณ ๋ ค ์ฌํญ ๋ฐ ํธํฅ: ์๋ฒฝํ ๊ต์ฐจ ๊ฒ์ฆ์ ์ฌ์ฉํ๋๋ผ๋ ์ด๊ธฐ ๋ฐ์ดํฐ์ ํธํฅ(์: ํน์ ์ธ๊ตฌ ํต๊ณ ๊ทธ๋ฃน ๋๋ ์ง์ญ์ ๊ณผ์ ๋ํ)์ด ํฌํจ๋์ด ์๋ค๋ฉด ๋ชจ๋ธ์ ์ด๋ฌํ ํธํฅ์ ์์ํํ ๊ฐ๋ฅ์ฑ์ด ๋์ต๋๋ค. ๊ต์ฐจ ๊ฒ์ฆ์ ์ผ๋ฐํ๋ฅผ ์ธก์ ํ๋ ๋ฐ ๋์์ด ๋์ง๋ง, ๊ณ ์ ํ ๋ฐ์ดํฐ ํธํฅ์ ํด๊ฒฐํ์ง๋ ์์ต๋๋ค. ์ด๋ฌํ ๋ฌธ์ ๋ฅผ ํด๊ฒฐํ๋ ค๋ฉด ์ข ์ข ๋ค์ํ ๋ฌธํ ๋ฐ ์ฌํ์ ๊ด์ ์ ์๊ฒฌ์ ์๋ ดํ์ฌ ์ ์คํ ๋ฐ์ดํฐ ์์ง ๋ฐ ์ ์ฒ๋ฆฌ๊ฐ ํ์ํฉ๋๋ค. \n
- ํ์ฅ์ฑ: ๋งค์ฐ ํฐ ๋ฐ์ดํฐ์ ์ ๊ฒฝ์ฐ ์ ์ฒด ๊ต์ฐจ ๊ฒ์ฆ์ด ๋ถ๊ฐ๋ฅํ ์ ์์ต๋๋ค. ์ด๊ธฐ ๋ชจ๋ธ ๊ฐ๋ฐ์ ์ํ ์๋ธ์ํ๋ง ๋๋ ๊ต์ฐจ ๊ฒ์ฆ์ ํจ์จ์ ์ผ๋ก ํตํฉํ๋ ํน์ ๋ถ์ฐ ๋จธ์ ๋ฌ๋ ํ๋ ์์ํฌ ์ฌ์ฉ๊ณผ ๊ฐ์ ๊ธฐ์ ์ ๊ณ ๋ คํ์ญ์์ค. \n
๊ฒฐ๋ก
\n\n๊ต์ฐจ ๊ฒ์ฆ์ ๋จ์ํ ๊ธฐ์ ์ด ์๋๋๋ค. ์ ๋ขฐํ ์ ์๊ณ ๋ฏฟ์ ์ ์๋ ๋จธ์ ๋ฌ๋ ๋ชจ๋ธ์ ๊ตฌ์ถํ๊ธฐ ์ํ ๊ทผ๋ณธ์ ์ธ ์์น์ ๋๋ค. Scikit-learn์ ๋ค์ํ ๊ต์ฐจ ๊ฒ์ฆ ์ ๋ต์ ๊ตฌํํ๊ธฐ ์ํ ๊ด๋ฒ์ํ๊ณ ์ ์ฐํ ํดํท์ ์ ๊ณตํ์ฌ ์ ์ธ๊ณ ๋ฐ์ดํฐ ๊ณผํ์๋ค์ด ๋ชจ๋ธ์ ์๊ฒฉํ๊ฒ ํ๊ฐํ๊ณ ์ ๋ณด์ ์ ๊ฐํ ๊ฒฐ์ ์ ๋ด๋ฆด ์ ์๋๋ก ํฉ๋๋ค.
\n\nK-Fold, ๊ณ์ธต๋ณ K-Fold, ์๊ณ์ด ๋ถํ , GroupKFold์ ์ฐจ์ด์ ๊ณผ ํ์ดํผํ๋ผ๋ฏธํฐ ํ๋ ๋ฐ ๊ฐ๋ ฅํ ํ๊ฐ์์ ์ด๋ฌํ ๊ธฐ์ ์ ์ค์ํ ์ญํ ์ ์ดํดํจ์ผ๋ก์จ ๋ชจ๋ธ ์ ํ์ ๋ณต์ก์ฑ์ ํค์ณ๋๊ฐ ์ค๋น๊ฐ ๋ ์ ๋์ด ์์ต๋๋ค. ํญ์ ๊ต์ฐจ ๊ฒ์ฆ ์ ๋ต์ ๋ฐ์ดํฐ์ ๊ณ ์ ํ ํน์ฑ ๋ฐ ๋จธ์ ๋ฌ๋ ํ๋ก์ ํธ์ ํน์ ๋ชฉํ์ ๋ง์ถ์ญ์์ค.
\n\n์ด๋ฌํ ์ ๋ต์ ์์ฉํ์ฌ ๋จ์ํ ์์ธก์ ๋์ด ๋ชจ๋ ๊ธ๋ก๋ฒ ์ปจํ ์คํธ์์ ์ง์ ์ผ๋ก ์ผ๋ฐํ ๊ฐ๋ฅํ๊ณ ๊ฐ๋ ฅํ๋ฉฐ ์ํฅ๋ ฅ ์๋ ๋ชจ๋ธ์ ๊ตฌ์ถํ์ธ์. Scikit-learn์ผ๋ก ๋ชจ๋ธ ์ ํ์ ๋ง์คํฐํ๊ธฐ ์ํ ์ฌ์ ์ด ์ด์ ๋ง ์์๋์์ต๋๋ค!